/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __K_DEFER_H__
#define __K_DEFER_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stdint.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <x_atomic.h>
#include <x_module.h>
/* includes (local) ----------------------------------------------------------*/
#include "k_errno.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/

#define ERRNO_DEFERRED_ILLEGAL_JOB ERRNO_JOIN(MID_DEFER, 1)
#define ERRNO_DEFERRED_ILLEGAL_PFN ERRNO_JOIN(MID_DEFER, 2)

/* typedefs ------------------------------------------------------------------*/

typedef struct deferred_job {
    struct deferred_job *next;
    void (*pfn)(uintptr_t);
    uintptr_t arg;
    atomic_uint busy;
} deferred_job_t;

/* macro ---------------------------------------------------------------------*/

/**
 * DEFERRED_JOB_INIT - create a initialized deferred job body
 */
#define DEFERRED_JOB_INIT(pfn, arg) {NULL, (void (*)(uintptr_t))pfn, (uintptr_t)arg, {0}}

/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

extern int deferred_job_sched(deferred_job_t *job);
extern int deferred_job_init(deferred_job_t *job, void (*pfn)(uintptr_t), uintptr_t arg);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __K_DEFER_H__ */
